<?php
namespace App\Wen\Utils;

use App\Http\Controllers\Api\Repositories\PostsRepositores;
use App\Http\Controllers\Api\Repositories\WxTagsRepositories;
use App\Jobs\CalculateFollowsNumJob;
use App\Jobs\CalculateLikesNumJob;
use App\Jobs\CollecterPublishCommentJob;
use App\Jobs\ImitateCircleJoinStepJob;
use App\Jobs\UserPublishedFollowJob;
use App\Models\Collecter\MiniCollecterCollected;
use App\Models\Collecter\MiniCollecterUserMap;
use App\Models\Posts\WxPostsGoods;
use App\Models\User\WxUser;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Redis;

class CollecterUtils{
    public static function init_post(){
        // status: 0 未发布
        return [
            'post_unique' => null,
            'author_unique' => null,
            'link' => '',
            'author' => '',
            'title' => '',
            'content' => '',
            'imgs' => [],
            'comments' => [],
            'tags' => [],
            'musics' => [],
            'videos' => [],
            'post_id' => 0,
            'circle_id' => 0,
            'status' => 0
        ];
    }
    static function init_comment(){
        return ['author_unique'=>null, 'comment'=>'', 'from'=>'', 'img'=>'', 'reply_unique'=>null, 'subcomments'=>[], 'comment_parent'=>0];
    }

    static function get_uid_from_unique($author_unique){
        if(_empty_($author_unique)){
            return null;
        }
        if(MiniCollecterUserMap::where('user_unique', $author_unique)->orWhere('user_unique1', $author_unique)->orWhere('user_unique2', $author_unique)->exists()){
            return MiniCollecterUserMap::where('user_unique', $author_unique)->orWhere('user_unique1', $author_unique)->orWhere('user_unique2', $author_unique)->value('user_id');
        }

        $bind_type = Settings::get('collecter_robot_bind_type', 1);

        if($bind_type >= 2){

            // 1: 2
            if(MiniCollecterUserMap::whereNull('user_unique1')->count() > 1000){
                $user_unique1_user = MiniCollecterUserMap::whereNull('user_unique1')->inRandomOrder()->first();
                if($user_unique1_user && $user_unique1_user->user_id > 0){
                    $r = MiniCollecterUserMap::where('user_unique', $user_unique1_user->user_unique)->update(['user_unique1'=>$author_unique]);
                    if($r){
                        // 17338
                        return $user_unique1_user->user_id;
                    }
                }
            }
        }

        if($bind_type >= 3){
            // 1: 3
            if(MiniCollecterUserMap::whereNull('user_unique2')->count() > 1000) {
                $user_unique2_user = MiniCollecterUserMap::whereNull('user_unique2')->inRandomOrder()->first();
                if ($user_unique2_user && $user_unique2_user->user_id > 0) {
                    $r = MiniCollecterUserMap::where('user_unique', $user_unique2_user->user_unique)->update(['user_unique2' => $author_unique]);
                    if ($r) {
                        return $user_unique2_user->user_id;
                    }
                }
            }
        }


        // 没有机器人
        $user_id = UserUtils::get_a_random_robot_uid([1]);
        $times = 100;

        while ($times >= 0 && MiniCollecterUserMap::where('user_id', $user_id)->exists()){
            WxUser::where('id', $user_id)->update(['is_robot' => 2]);

            $user_id = UserUtils::get_a_random_robot_uid([1]);
            $times -= 1;
        }

        if($times < 0){
            throw new \Exception('可用的空闲机器人太少');
        }

        if($user_id && $author_unique){
            $MiniCollecterUserMap = new MiniCollecterUserMap();
            $MiniCollecterUserMap->user_unique = $author_unique;
            $MiniCollecterUserMap->user_id = $user_id;
            $r = $MiniCollecterUserMap->save();
            if($r){
                WxUser::where('id', $user_id)->update(['is_robot' => 2]);
                return $user_id;
            }
        }
        return null;
    }

    static function check_post(&$post){
        if(_empty_($post) || !is_array($post)){
            throw new \Exception('空非法');
        }
        if(_empty_(_array_key($post, 'post_unique', null))){
            throw new \Exception('post_unique不能为空');
        }
        if(_empty_(_array_key($post, 'author_unique', null))){
            throw new \Exception('author_unique不能为空');
        }

        if(!_empty_(_array_key($post, 'user_id', null))){
            if(!is_numeric(_array_key($post, 'user_id', null))){
                throw new \Exception('user_id非法');
            }
        }
//        if(_empty_(_array_key($post, 'circle_id', null))){
//            return false;
//        }
        if(_empty_(_array_key($post, 'title', null)) && _empty_(_array_key($post, 'content', null))){
            throw new \Exception('title和content必须其中之一不为空');
        }

        if(!_empty_(_array_key($post, 'imgs', null))){
            $imgsarr = _array_key($post, 'imgs', null);
            foreach ($imgsarr as $img_str){
                if(!is_string($img_str)){
                    throw new \Exception('imgs参数的url不是字符串');
                }
                if(!StrUtils::startsWith($img_str, 'http')){
                    throw new \Exception('imgs参数的url非法');
                }
            }
        }

        if(!_empty_(_array_key($post, 'tags', null))){
            $tagsarr = _array_key($post, 'tags', null);
            foreach ($tagsarr as $tag_str){
                if(!is_string($tag_str)){
                    throw new \Exception('tags参数的tag非法');
                }
            }
        }

        if(!_empty_(_array_key($post, 'tenant_id', 0))){
            global $__MINI_GLOBAL_TENANTS_ARR__;
            if(!in_array(_array_key($post, 'tenant_id', null) , $__MINI_GLOBAL_TENANTS_ARR__)){
                throw new \Exception('tenant_id不合法或者未授权');
            }
        }else{
            $post['tenant_id'] = 0;
        }

        if(!_empty_(_array_key($post, 'comments', ''))){
            $comment_arr = json_decode(_array_key($post, 'comments', '[]'), true);
            if(_empty_($comment_arr)){
                throw new \Exception('评论json不能解析或不完整');
                $post['comments'] = '[]';
            }else{
                foreach ($comment_arr as $comment){
                    if(_empty_(_array_key($comment, 'author_unique', ''))){
                        throw new \Exception('评论格式非法，author_unique不得为空');
                    }
                    if(_empty_(_array_key($comment, 'comment', '')) && _empty_(_array_key($comment, 'img', ''))){
                        throw new \Exception('评论格式非法，评论内容和评论图片都为空');
                    }
                    if(!_empty_(_array_key($comment, 'subcomments', []))){
                        $subcomments = _array_key($comment, 'subcomments', []);
                        foreach ($subcomments as $subcomment){

                            if(_empty_(_array_key($subcomment, 'author_unique', ''))){
                                throw new \Exception('子评论格式非法，author_unique不得为空');
                            }
                            if(_empty_(_array_key($subcomment, 'comment', '')) && _empty_(_array_key($subcomment, 'img', ''))){
                                throw new \Exception('子评论格式非法，评论内容和评论图片都为空');
                            }

                        }
                    }
                }
            }
        }

        if(MiniCollecterCollected::where('post_unique', _array_key($post, 'post_unique', null))->exists()){
            throw new \Exception('根据post_unique判断，该内容已重复');
        }
    }

    static function repair_url($url){
        if(_empty_($url)){
            return '';
        }
        if(strpos($url, '//') === 0){
            return 'https:'. $url;
        }
        return $url;
    }

    public static function imgurl_filter($url){
        if(_empty_($url)){
            return '';
        }
        if (strpos($url, 'emot') !== false) {
            return '';
        }
        if(strpos($url,'face')!==false){
            return '';
        }
        if(strpos($url,'smile')!==false){
            return '';
        }
        return $url;
    }

    static function content_media_process($content, $uid = 0){
        if(_empty_($content)){
            return '';
        }
        // 处理图片
        $content = preg_replace_callback("/<img.*?src[^\'\"]+[\'\"]([^\"\']+)[^>]+>/is", function ($r) use ($uid){
            $url = self::imgurl_filter( self::repair_url( $r[1] ));
            if(_empty_($url)){
                return '';
            }

            $process_url = ImageUtils::upload_url_img($url, '', [], [], true, $uid, 1, 3);
            if($process_url && _array_key($process_url, 'url', '') ){
                return '<img src="'. $process_url['url'] . '">';
            }
            return '';

        }, $content);

        // 处理视频（todo: 暂时抛弃视频）
        $content = preg_replace_callback("/<video.*?src[^\'\"]+[\'\"]([^\"\']+)[^>]+>/is", function ($r){
            return '';
        }, $content);

        // 处理链接
        $content = preg_replace_callback("/<a.*?href[^\'\"]+[\'\"]([^\"\']+)[^>]+>/is", function ($r){
            return $r[1];
        }, $content);
        return $content;
    }

    static function download_img_arr($img_arr, $uid = 0, $scene = 0){
        if(_empty_($img_arr)){
            return [];
        }
        $res_arr = [];
        foreach ($img_arr as $url){
            $url = self::imgurl_filter( self::repair_url( $url ));
            if(_empty_($url)){
                continue;
            }
            $process_url = ImageUtils::upload_url_img($url, '', [], [], true, $uid, 1, $scene);
            if($process_url && _array_key($process_url, 'url', '') ){
                $res_arr[] = $process_url['url'];
            }

        }
        return $res_arr;
    }

    static function is_collected_post($post_unique){
        if(_empty_($post_unique)){
            return true;
        }
        return MiniCollecterCollected::withTrashed()->where('post_unique', $post_unique)->exists();
    }

    static function save_posts($posts){
        if(_empty_($posts)){
            return null;
        }
        $results = [];
        foreach ($posts as $post){
            self::check_post($post);
            $Collected = new MiniCollecterCollected();
            $Collected->post_unique = $post['post_unique'];
            $Collected->author_unique = $post['author_unique'];
            $Collected->link = _array_key($post, 'link', '');
            $Collected->author = _array_key($post, 'author', '');
            $Collected->title = _array_key($post, 'title', '');
            $Collected->content = _array_key($post, 'content', '');
            $Collected->imgs = _array_key($post, 'imgs', '') ? json_encode(_array_key($post, 'imgs', [])) : '[]';
            $Collected->comments = _array_key($post, 'comments', '') ? _array_key($post, 'comments', '') : '[]';
            $Collected->tags = _array_key($post, 'tags', '') ? json_encode(_array_key($post, 'tags', '')) : '[]';
            $Collected->musics = _array_key($post, 'musics', '') ? json_encode(explode(',', _array_key($post, 'musics', ''))) : '[]';
            $Collected->videos = _array_key($post, 'videos', '') ? json_encode(explode(',', _array_key($post, 'videos', ''))) : '[]';
            $Collected->post_id = 0;
            $Collected->circle_id = _array_key($post, 'circle_id', 0);
            $Collected->user_id = _array_key($post, 'user_id', 0);
            $Collected->tenant_id = _array_key($post, 'tenant_id', 0);
            $Collected->status = 0;
            $Collected->save();
            $results[] = $Collected->id;
        }
        return $results;
    }

    public static function publish($collecter_id){
        $collected = MiniCollecterCollected::where('status', 1)->where('id', $collecter_id)->first();
        if(!$collected){
            return ;
        }
        if(!_empty_($collected->user_id)){
            $uid = $collected->user_id;
        }else{
            $uid = CollecterUtils::get_uid_from_unique($collected->author_unique);
        }

        if(_empty_($uid)){
            UserUtils::assistant_notice('admin', '没有未绑定的机器人，请新增机器人，才能发布');
            throw new \Exception('没有未绑定的机器人，请新增机器人，才能发布');
        }
        $user_name = WxUser::where('id', $uid)->value('user_name');
        $circle_id = $collected->circle_id;
        $tag_ids = [];
        $collected_comments = json_decode($collected->comments, true);
        if(_empty_($collected_comments)){
            $collected_comments = [];
        }

        if($collected->tags){
            foreach (json_decode($collected->tags, true) as $tag_name){
                try{
                    $tag_ids[] = WxTagsRepositories::add($uid, $tag_name)->id;
                }catch (\Exception $e){
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }
        $date = timetostr(time() - mini_rand(60, 600));
        if(_empty_($collected->title)){
            $post_content = $collected ->content;
        }else if(_empty_($collected ->content)){
            $post_content = $collected->title;
        }else{
            $post_content = $collected->title .'<br/>'. $collected ->content;
        }

        if($collected->author){
            $post_content = str_replace($collected->author, $user_name, $post_content);
        }

        // 笔记图片
        $image_urls = '';
        $collect_imgs = json_decode($collected->imgs, true);
        if($collect_imgs && count($collect_imgs) > 0){
            $image_urls = implode(',', $collect_imgs);
        }

        if(is_string($collected->videos)){
            $collected->videos = json_decode($collected->videos, true);
        }
        $video_url = '';
        if($collected->videos && $collected->videos[0]){
            if(strpos($collected->videos[0], 'http') === 0){
                $video_url = $collected->videos[0];
            }
        }

        $post_id = PostsRepositores::admin_add('', $uid, '',$post_content,
            $circle_id, $tag_ids, [], $image_urls, $video_url, null, '', $date, $collected->tenant_id);
        $collected->status = 2;
        $collected->post_id = $post_id;
        $collected->save();
        if($post_id){
            UserUtils::add_user_experience($uid, 1);
            _mini_aite($uid, $post_content, 1, false, $post_id);
            // 处理评论
            if(!_empty_($collected_comments) && is_array($collected_comments)){
                $i = 0;
                $last_time = now();

                $comment_unique_ids = [];
                foreach (array_reverse($collected_comments) as $comment){
                    if(!_empty_(_array_key($comment, 'comment_unique', ''))){
                        if(in_array(_array_key($comment, 'comment_unique', ''), $comment_unique_ids)){
                            continue;
                        }else{
                            $comment_unique_ids[] = _array_key($comment, 'comment_unique', '');
                        }
                    }
                    $last_time = $last_time->addMinutes(mini_rand(1, 10) + $i * mini_rand(1, 5) );
                    CollecterPublishCommentJob::dispatch($comment, $post_id, 0)->delay($last_time);
                    $i ++;
                }
            }

            // 处理商品链接关系
            preg_match_all('$<shopcard id="(\d+)" img="([^\s]+)" title="(.*?)" price="([\d\.]+)"></shopcard>$', $collected ->content, $matches);
            if($matches && $matches[1]){
                foreach ($matches[1] as $goods_id){
                    $postGood = new WxPostsGoods();
                    $postGood->posts_id = $post_id;
                    $postGood->goods_id = $goods_id;
                    $postGood->type = 1;
                    $postGood->save();
                }
            }

            GatewayUtils::success('all', 6);
            _logger_(__file__, __line__, '发布成功'.$post_id);

            UserPublishedFollowJob::dispatch($uid, $circle_id, '');
            ImitateCircleJoinStepJob::dispatch($circle_id, mini_rand(1, 100) <= 50 ? mini_rand(1, 2) : 0)->delay(now()->addMinutes(mini_rand(1, 20)));
            // 机器人点赞
            CalculateLikesNumJob::dispatch($post_id);
            CalculateFollowsNumJob::dispatch($uid);
            Redis::sadd('realtime:post:set', $post_id);
        }
    }

}
